import React from 'react'
import axios from 'axios'
import { Toast } from 'antd-mobile';
import { getCurrentCity } from '../../utils'
import { List, AutoSizer } from 'react-virtualized'
import './index.css'

// 导入navHeader组件
import NavHeader from '../../components/NavHeader';

// 接口返回的数据格式
// [{"label":"北京","value":"","pinyin":"beijing","short":"bj"}]
// 渲染城市列表的数据格式为：
// {a:[{},{}],b:[{},...]}
// 渲染右侧索引的数据格式
// ['a','b']
// 数据格式化的方法
// list: [{},{}]

// 导入 CSSModules 的样式文件
// import styles from './index.module.css'
const formatCityData = (list) => {
    const cityList = {}
    // const cityIndex = []

        // 1、遍历list数组
    list.forEach(item =>{
        // 2、获取每一个城市首字母
        const first = item.short.substr(0,1)
        // 3、判断cityList中是否有该分类
        if(cityList[first]) {
        // 4、若有，直接往该分类中push数据
        cityList[first].push(item)
        } else {
        // 5、如果没有，就先创建一个数组，然后把当前城市信息添加到数组中
        cityList[first] = [item]
        }
    })

    // 获取索引数据
    const cityIndex = Object.keys(cityList).sort()

    return {
        cityList,
        cityIndex
    }
}

// 有房源的城市
const HOUSE_CITY = ['北京','上海','广州','深圳']
// List data as an array of strings
const list = Array(100).fill('react-virtualized')

// 索引(A,B等)的高度
const TITLE_HEIGHT = 36
// 每个城市名称的高度
const NAME_HEIGHT = 50

// 封装处理字母索引
const formatCityIndex = (letter) =>{
    switch (letter) {
        case "#":
            return '当前定位'
        case "hot":
            return '热门城市'
        default:
            return letter.toUpperCase()
    }
}

export default class CityList extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
        cityList: {},
        cityIndex: [],
        // 指定右侧字母索引列表高亮的索引号
        activeIndex:0
    }

    // 创建ref对象
    this.cityListComponent = React.createRef()
  }
    async componentDidMount() {
        await this.getCityList()

        // 调用measureAllRows,提前计算List中每一行高度，实现scrollToRow精度跳转
        // 注意： 调用这个方法时，需要保证List组件中已经有数据了！如果List组件中的数据为空，就会导致调用方法报错
        // 解决： 只要保证这个方法是在 获取到数据之后 调用的即可
        this.cityListComponent.current.measureAllRows()
    }

    // 获取城市列表
    async getCityList() {
        const res = await axios.get('http://localhost:3000/area/city?level=1')
        const {cityList,cityIndex} = formatCityData(res.data.body)

        /*
          1、获取热门城市数据
          2、将数据添加到cityList中
          3、将索引添加到cityIndex
        */
       const hotRes = await axios.get('http://localhost:3000/area/hot')
       // 添加一个键名为hot的值
       cityList['hot'] = hotRes.data.body
       // 将索引添加到cityIndex
       cityIndex.unshift('hot')

       // 获取当前定位城市
       const curCity = await getCurrentCity()

       /*
        1.将当前城市定位数据添加到cityList中
        2.将当前城市定位索引添加到cityIndex中
       */
      cityList['#'] = [curCity]
      cityIndex.unshift('#')

      this.setState({
          cityList,
          cityIndex
      })
    }

    /* 
    1 给城市列表绑定点击事件
    2 判断当前城市是否有房源数据
    3 如果有房源数据，则保存当前城市数据到本地缓存，并返回上一页
    4 如果没有房源数据，则提示用户：该城市暂无房源数据，不执行任何操作
    */

    changeCity({label,value}) {
      if(HOUSE_CITY.indexOf(label) > -1) {
        // 有
        localStorage.setItem('rent_house',JSON.stringify({label,value}))
        this.props.history.go(-1)
      } else {
        Toast.info('该城市暂无房源数据',1,null,false)
      }
    }

    // List组件渲染每一行的方法
    rowRenderer = ({
        key, // Unique key within array of rows
        index, // Index of row within collection
        isScrolling, // 当前项是否正在滚动中
        isVisible, // 当前项在list中时可见的
        style, // 注意：重点属性，一定要给每一行数据添加该样式！ 作用：指定每一行的样式
      }) => {

        // 获取每一行字母索引
        const {cityIndex,cityList} = this.state
        const letter = cityIndex[index]

        // 获取指定字母索引下的城市列表
        // console.log(cityList[letter]);

        // 函数的返回值表示最终渲染在页面上的内容
        return (
          <div key={key} style={style} className="city">
            {/* {index} {list[index]}{isScrolling+''}{isVisible+''} */}
            <div className="title">Y</div>
            {/* <div className="title">{formatCityIndex(letter)}</div> */}
            <div className="name">宜昌</div>
            {/* {
                cityList[letter].map(item => <div className="name" key={item.value} onClick={() =>this.changeCity(item)}>宜昌</div>)
            } */}
          </div>
        );
      }

    // 创建动态计算每一行高度的算法
    getRowHeight = ({index}) => {
        // 标索引题高度 + 城市数量 * 城市名称高度
        const {cityList,cityIndex} = this.state
        return TITLE_HEIGHT + cityList[cityIndex[index]].length * NAME_HEIGHT
    }

    /*
    1 给索引列表绑定点击事件
    2 点击事件中，通过index获取当前项索引号
    3 调用List组件的scrollToRow方法，让List组件滚动到指定行
    3.1 在constructor中，调用React.createRef()创建ref对象
    3.2 将创建好的ref对象，添加为List组件的ref属性
    3.3 通过ref的current属性，获取组件实例，再调用组件的scrollToRow方法

    4 设置List组件的scrollToAlignment配置项值为start,保证被点击行出现再页面顶部
    5 对于点击索引无法正确定位的问题，调用List组件measureAllRows方法，提前计算高度来解决
    */

    // 封装渲染右侧索引列表的方法
    renderCityIndex() {
        // 获取到 cityIndex,并便利其，实现渲染
        const {cityIndex,activeIndex} = this.state
        return this.state.cityIndex.map((item,index)=>(
          <li 
          className="city-index-item" 
          key={item} 
          onClick={() => {
            this.cityListComponent.current.scrollToRow(index)
            // scrollToAlignment = "start"
          }}>
            <span className={this.state.activeIndex === index ? "index-active" : ""}>
              {item === 'hot' ? '热' : item.toUpperCase()}
            </span>
          </li>
        ))
    }
    render() {
        return <div className="citylist">
            {/* 顶部导航栏 */}
            <NavHeader>城市选择</NavHeader>

            {/* 城市列表 */}               
            <AutoSizer>
              {({height, width}) => (
                <List
                  ref = {this.cityListComponent}
                  height={height}
                  rowCount={list.length}
                //   rowCount={this.state.cityIndex.length}
                  rowHeight={100}
                // rowHeight={this.getRowHeight}
                  rowRenderer={this.rowRenderer}
                  width={width}
                />
              )}
            </AutoSizer> 

            {/* 右侧索引列表 */}
            <ul className="city-index">
                {this.renderCityIndex()}
            </ul>
        </div>
    }
}